/*
 * CS_REQ_SHOP_BUY_ITEM.cpp
 *
 *  Created on: 2013. 5. 27.
 *      Author: the2
 */

#include "../../Command.h"
#include "../../NResource/Static.h"
#include "../../NLogic/Item.h"
#include "../../NLogic/Bag.h"
#include "../../NLogic/Drop.h"
#include "../../NLogic/VirtualCurrency.h"
#include "../../User.h"
#include "../../GameLog.h"

namespace ProjectZ { namespace NCommand {

void SendFailShopBuyItem(User * pUser, int res, uint64_t item_seq)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	*pAck << static_cast<int16_t>(res);
	*pAck << item_seq;
	*pAck << pUser->GetCharacterInfo().gold;
	*pAck << pUser->GetVirtualCurrency()->GetZen();

	pAck->MakePacket(CMD_SC_REQ_SHOP_BUY_ITEM);

	pUser->Send(pAck);
}

void Command::CS_REQ_SHOP_BUY_ITEM(User * pUser, ::Network::Packet * pPacket)
{

	PREPARE_PACKET;

	uint8_t shopType		= 0;	// 0:일반상점, 1:암흑상인
	uint8_t sheetType		= 0;
	uint16_t itemTid		= 0;
	int8_t itemQuantity	= 0;	// 구매 수량

	*pPacket >> shopType;
	*pPacket >> sheetType;
	*pPacket >> itemTid;
	*pPacket >> itemQuantity;

	if (itemQuantity <= 0)
	{
		SendFailShopBuyItem(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	NResource::ItemResource * pItemResource	= NResource::Static::InstancePtr()->GetItemResource();
	if (NULL == pItemResource)
	{
		DEBUGLOG("CS_REQ_SHOP_BUY_ITEM : pItemResource is NULL!!");
		return;
	}

	// 구매 아이템 정보 설정
	NLogic::Item::Data clsData;

	int itemPrice		= 0;

	if (0 == shopType)
	{
		// NPC상점에서 아이템을 구매하는 경우
		// 세트 아이템 여부를 결정하지 않기 위해
		// Flag 값으로 -99를 일단 넣어두고, GetItemSettedType 함수에서 체크한다
		clsData.set_type	= -99;

		// 등급은 F 등급
		clsData.quality		= 0;

		if (false == pItemResource->SetItemFromXLS(pUser, clsData, sheetType, itemTid, itemQuantity))
		{
			DEBUGLOG("CS_REQ_SHOP_BUY_ITEM : Ooops!!! INVALID ITEM. sheet=%d, tid=%d, quantity=%d, userseq=%d", sheetType, itemTid, itemQuantity, pUser->GetUserSeq());
			return;
		}

		itemPrice = pItemResource->GetItemPrice(clsData);
		itemPrice = itemPrice * itemQuantity;
	}
	else if (1 == shopType)
	{
		// 암흑상인인 경우 던전 드랍과 같은 확률로 등급 결정
		NResource::BalanceData * pBalance = NResource::Static::InstancePtr()->GetBalance()->GetBalancePtr(pUser);
		if (NULL == pBalance)
		{
			DEBUGLOG("%s : pBalance is NULL!", __FUNCTION__);
			return;
		}

		NLogic::Drop clsDrop;
		clsData.quality	= clsDrop.GetDropItemQuality(pBalance, 0);
		if (false == pItemResource->SetItemFromXLS(pUser, clsData, sheetType, itemTid, itemQuantity))
		{
			DEBUGLOG("CS_REQ_SHOP_BUY_ITEM : Ooops!!! INVALID ITEM. sheet=%d, tid=%d, quantity=%d, userseq=%d", sheetType, itemTid, itemQuantity, pUser->GetUserSeq());
			return;
		}
//		pItemResource->SetAdditionalEffect(clsData);
		itemPrice = pItemResource->GetItemPrice(clsData) * 2;	// 암흑상인에게 구매시 아이템 가격 2배
		itemPrice = itemPrice * itemQuantity;
	}
	else
	{
		SendFailShopBuyItem(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	if (1 != pItemResource->getItemSaleType(clsData))
	{
		DEBUGLOG("CS_REQ_SHOP_BUY_ITEM : Ooops!!! INVALID ITEM. sheet=%d, tid=%d, quantity=%d, userseq=%d", sheetType, itemTid, itemQuantity, pUser->GetUserSeq());
		SendFailShopBuyItem(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	// 소지 골드 부족
	if (pUser->GetCharacterInfo().gold < static_cast<uint32_t>(itemPrice))
	{
		SendFailShopBuyItem(pUser, ACK_NOT_ENOUGH_GOLD, 0);
		return;
	}

	NLogic::Bag * pBag = pUser->GetBag(static_cast<INVEN_BAG_TYPE>(clsData.bag_type));
	if (NULL == pBag)
	{
		SendFailShopBuyItem(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	bool bBagFull = false;
	NLogic::Item * pItem = pBag->AddItemWithData(clsData, bBagFull);

	if (true == bBagFull)
	{
		SendFailShopBuyItem(pUser, ACK_INVEN_BAG_FULL, 0);
		return;
	}

	if (NULL == pItem)
	{
		DEBUGLOG("CS_REQ_SHOP_BUY_ITEM : pItem is NULL!!!");
		return;
	}

	// 골드 차감
//	pUser->GetCharacterInfo().gold -= itemPrice;
	NLogic::NFunction::ModifyGold(pUser, itemPrice * -1);
	NGameLog::LogGoldInfo(pUser, BUY_STORE, itemPrice * -1);

	// 응답
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << static_cast<int16_t>(ACK_OK);
	*pAck << pItem->GetItemSeq();
	*pAck << pUser->GetCharacterInfo().gold;
	*pAck << pUser->GetVirtualCurrency()->GetZen();
	pAck->MakePacket(CMD_SC_REQ_SHOP_BUY_ITEM);
	pUser->Send(pAck);
}

} /*NCommand*/ } /*ProjectZ*/
